#include "Camera.h"
#include "MatrixHelper.h"
#include "WindowManager.h"
#include "MathHelper.h"
#include "Plane.h"

Camera::Camera() : m_fFieldOfView(CAMERA_DEFAULT_FIELDOFVIEW), m_fNearPlaneDistance(CAMERA_DEFAULT_NEARPLANEDISTANCE), m_fFarPlaneDistance(CAMERA_DEFAULT_FARPLANEDISTANCE)
{
}

Camera::~Camera()
{
}

const float Camera::GetFieldOfView() const
{
	return m_fFieldOfView;
}

const float Camera::GetNearPlaneDistance() const
{
	return m_fNearPlaneDistance;
}

const float Camera::GetFarPlaneDistance() const
{
	return m_fFarPlaneDistance;
}

const BoundingFrustum Camera::GetBoundingFrustum() const
{
	return m_oBoundingFrustum;
}

void Camera::SetFieldOfView(float fieldOfView)
{
	m_fFieldOfView = fieldOfView;
}

void Camera::SetNearPlaneDistance(float nearPlaneDistance)
{
	m_fNearPlaneDistance = nearPlaneDistance;
}

void Camera::SetFarPlaneDistance(float farPlaneDistance)
{
	m_fFarPlaneDistance = farPlaneDistance;
}

void Camera::SetBoundingFrustum(const BoundingFrustum& boundingFrustum)
{
	m_oBoundingFrustum = boundingFrustum;
}

void Camera::Update(float elapsedTime)
{
	Matrix view;
	float aspectRatio = WindowManager::GetAspectRatio();
	Vector3f position = GetPosition();
	Vector3f right, up, forward;
	Quaternion rotation = GetRotation();

	position = GetPosition();
	rotation = GetRotation();

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glGetFloatv(GL_MODELVIEW_MATRIX, view);

	MatrixHelper::SetRotation(view, rotation);
	MatrixHelper::GetRight(view, right);
	MatrixHelper::GetUp(view, up);
	MatrixHelper::GetForward(view, forward);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(m_fFieldOfView, aspectRatio, m_fNearPlaneDistance, m_fFarPlaneDistance);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	Vector3f center = position + forward;

	gluLookAt(position.X, position.Y, position.Z, center.X, center.Y, center.Z, up.X, up.Y, up.Z); 

	m_oBoundingFrustum.Update(m_fFieldOfView, aspectRatio, m_fNearPlaneDistance, m_fFarPlaneDistance, position, right, up, forward);

	Actor::Update(elapsedTime);
}